/*
 * Copyright (c) 2025 Industrial Software Feature Database
 */
package com.comac.ins.isfd.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.comac.ins.common.core.exception.ServiceException;
import com.comac.ins.common.core.exception.base.BaseException;
import com.comac.ins.common.core.utils.MapstructUtils;
import com.comac.ins.common.core.utils.StreamUtils;
import com.comac.ins.common.core.utils.StringUtils;
import com.comac.ins.common.core.utils.file.FileUtils;
import com.comac.ins.common.mybatis.core.page.PageQuery;
import com.comac.ins.common.mybatis.core.page.TableDataInfo;
import com.comac.ins.common.oss.constant.OssConstant;
import com.comac.ins.common.oss.core.OssClient;
import com.comac.ins.common.oss.entity.UploadResult;
import com.comac.ins.common.oss.enumd.AccessPolicyType;
import com.comac.ins.common.oss.factory.OssFactory;
import com.comac.ins.isfd.domain.IsfdResultGeneralPreprocess;
import com.comac.ins.isfd.domain.bo.IsfdResultGeneralPreprocessBo;
import com.comac.ins.isfd.domain.vo.IsfdMeshModelStructureDefinitionVo;
import com.comac.ins.isfd.domain.vo.IsfdResultGeneralPreprocessVo;
import com.comac.ins.isfd.mapper.IsfdResultGeneralPreprocessMapper;
import com.comac.ins.isfd.service.IIsfdCollectBatchHistoryService;
import com.comac.ins.isfd.service.IIsfdCollectRoundHistoryService;
import com.comac.ins.isfd.service.IIsfdMeshModelStructureDefinitionService;
import com.comac.ins.isfd.service.IIsfdResultGeneralPreprocessService;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.List;

/**
 * 结构分析通用前处理结果库Service业务层处理
 *
 * @author Lion Li
 * @date 2025-08-29
 */
@RequiredArgsConstructor
@Service
public class IsfdResultGeneralPreprocessServiceImpl implements IIsfdResultGeneralPreprocessService {

    @Autowired
    private IsfdResultGeneralPreprocessMapper baseMapper;

    @Autowired
    private IIsfdCollectBatchHistoryService iIsfdCollectBatchHistoryService;

    @Autowired
    private IIsfdMeshModelStructureDefinitionService iIsfdMeshModelStructureDefinitionService;

    @Autowired
    private IIsfdCollectRoundHistoryService iIsfdCollectRoundHistoryService;

    @Value("${evn.evnType}")
    private String evnType;


    /**
     * 分页查询结构分析通用前处理结果库列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 结构分析通用前处理结果库分页列表
     */
    @Override
    public TableDataInfo<IsfdResultGeneralPreprocessVo> queryPageList(IsfdResultGeneralPreprocessBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<IsfdResultGeneralPreprocess> lqw = buildQueryWrapper(bo);
        Page<IsfdResultGeneralPreprocessVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        List<IsfdResultGeneralPreprocessVo> filterResult;
        if(evnType.equals("red")){
            filterResult = StreamUtils.toList(result.getRecords(), this::SignUrl);
        }else{
            filterResult = StreamUtils.toList(result.getRecords(), this::matchingUrl);
        }
        result.setRecords(filterResult);
        return TableDataInfo.build(result);
    }

    private LambdaQueryWrapper<IsfdResultGeneralPreprocess> buildQueryWrapper(IsfdResultGeneralPreprocessBo bo) {
        LambdaQueryWrapper<IsfdResultGeneralPreprocess> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getFileName()), IsfdResultGeneralPreprocess::getFileName, bo.getFileName());
        lqw.eq(StringUtils.isNotBlank(bo.getModelNumber()), IsfdResultGeneralPreprocess::getModelNumber, bo.getModelNumber());
        lqw.like(StringUtils.isNotBlank(bo.getBatchNumber()), IsfdResultGeneralPreprocess::getBatchNumber, bo.getBatchNumber());
        lqw.like(StringUtils.isNotBlank(bo.getSectionNumber()), IsfdResultGeneralPreprocess::getSectionNumber, bo.getSectionNumber());
        lqw.like(StringUtils.isNotBlank(bo.getSectionName()), IsfdResultGeneralPreprocess::getSectionName, bo.getSectionName());
        lqw.like(StringUtils.isNotBlank(bo.getRoundNumber()), IsfdResultGeneralPreprocess::getRoundNumber, bo.getRoundNumber());
        lqw.orderByDesc(IsfdResultGeneralPreprocess::getCreateTime);
        return lqw;
    }

    /**
     * 新增结构分析通用前处理结果库
     *
     * @param bo 结构分析通用前处理结果库
     * @return 是否新增成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertByBo(IsfdResultGeneralPreprocessBo bo) {
        // 校验入参
        validEntityBeforeSave(bo);
        IsfdResultGeneralPreprocess add = MapstructUtils.convert(bo, IsfdResultGeneralPreprocess.class);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    @Override
    public Boolean save(MultipartFile file, IsfdResultGeneralPreprocessBo bo) {
        // 上传文件至OSS
        String originalFileName = new File(file.getOriginalFilename()).getName();
        String fileName = originalFileName; // 带后缀
        String suffix = ""; // 后缀，带点

        int dotIndex = originalFileName.lastIndexOf('.');
        if (dotIndex >= 0) {
            suffix = originalFileName.substring(dotIndex); // 只取后缀
        }

        OssClient storage = OssFactory.instance(OssConstant.PREPROCESSING_CONFIG_KEY);
        UploadResult uploadResult;
        try {
            uploadResult = storage.uploadSuffix(file.getBytes(), suffix);
        } catch (IOException e) {
            throw new ServiceException(e.getMessage());
        }
        bo.setFileName(fileName);
        bo.setUrl(uploadResult.getUrl());
        bo.setFilePath(uploadResult.getFilename());
        // 保存模型信息
        return insertByBo(bo);
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(IsfdResultGeneralPreprocessBo entity){
        // 检查modelNumber
        String modelNumber = entity.getModelNumber();
        IsfdMeshModelStructureDefinitionVo modelIndex = iIsfdMeshModelStructureDefinitionService.queryOneByQueryIndex(modelNumber, null, null);
        if (modelIndex == null) {
            throw new BaseException("机型" + modelNumber + " 未定义");
        }
        entity.setModelName(modelIndex.getName());

        // 检查 sectionNumber
        String sectionNumber = entity.getSectionNumber();
        IsfdMeshModelStructureDefinitionVo sectionIndex = iIsfdMeshModelStructureDefinitionService.queryOneByQueryIndex(modelNumber, sectionNumber, null);
        if (sectionIndex == null) {
            throw new BaseException("部段" + sectionNumber + " 未定义");
        }
        entity.setSectionName(sectionIndex.getName());

        // 处理batchNumber
        String batchNumber = entity.getBatchNumber();
        entity.setBatchName(batchNumber);
        iIsfdCollectBatchHistoryService.save(sectionNumber, batchNumber);

        // 处理roundNumber
        String roundNumber = entity.getRoundNumber();
        entity.setRoundName(roundNumber);
        iIsfdCollectRoundHistoryService.save(modelNumber, roundNumber);
    }

    /**
     * 校验并批量删除结构分析通用前处理结果库信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        List<IsfdResultGeneralPreprocess> pos = baseMapper.selectBatchIds(ids);
        for (IsfdResultGeneralPreprocess po : pos) {
//            deleteFileOnOss(po);
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    private void deleteFileOnOss(IsfdResultGeneralPreprocess po) {
        String url = po.getUrl();
        if (StringUtils.isEmpty(url)) {
            return;
        }
        OssClient storage = OssFactory.instance();
        storage.delete(url);
    }


    private IsfdResultGeneralPreprocessVo matchingUrl(IsfdResultGeneralPreprocessVo resultVo) {
        OssClient storage = OssFactory.instance();
        // 仅修改桶类型为 private 的URL，临时URL时长为120s
        if (AccessPolicyType.PRIVATE == storage.getAccessPolicy()) {
            resultVo.setUrl(storage.getPrivateUrl(resultVo.getFileName(), 120));
        }
        return resultVo;
    }
    private IsfdResultGeneralPreprocessVo SignUrl (IsfdResultGeneralPreprocessVo resultVo) {
        OssClient storage = OssFactory.instance(OssConstant.PREPROCESSING_CONFIG_KEY);
        resultVo.setUrl(storage.OssSignedUrl(resultVo.getFilePath()));
        return resultVo;
    }


    @Override
    public void download(Long modelId, HttpServletResponse response) throws IOException {
        IsfdResultGeneralPreprocessVo vo = baseMapper.selectVoById(modelId);
        if (ObjectUtil.isNull(vo)) {
            throw new ServiceException("文件数据不存在!");
        }
        FileUtils.setAttachmentResponseHeader(response, vo.getFileName());
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE + "; charset=UTF-8");
        OssClient storage = OssFactory.instance(OssConstant.PREPROCESSING_CONFIG_KEY);
        long contentLength = storage.download(vo.getFilePath(), response.getOutputStream());
        response.setContentLengthLong(contentLength);
    }
}
